package top.kaoshanji.p2ch23a;

import java.lang.reflect.Proxy;

/**
 * 代码清单-p2ch23a-582页a：通用的动态代理类示例
 * author kaoshanji
 * ^_^
 * create time 2025/3/3 10:44
 */
public class GeneralProxyDemo {

    public static void main(String[] args) {
        GeneralProxyDemo demo = new GeneralProxyDemo();

        // 对象A，有个A方法
        IServiceA a = new ServiceAImpl();
        IServiceA aProxy = demo.getProxy(IServiceA.class, a);
        String str = aProxy.sayHello();
        System.out.println("IServiceA: " + str);


        // 对象B，有个B方法
        IServiceB b = new ServiceBImpl();
        IServiceB bProxy = demo.getProxy(IServiceB.class, b);
        bProxy.fly();

    }

    // 对外暴露的是两个参数，是因为只需要外部传入两个
    // 但是，真正发挥作用的是隐藏的 GeneralInvocationHandler
    // 对 realObj对象，realObj对象 的调用，都转到了 GeneralInvocationHandler#invoke 方法
    // 而 realObj对象 是个参数，就是说，任何对象都可以传递进来，这才是 动态代理的 关键所在
    // 但是 这里的 GeneralInvocationHandler 只有一个，也就是说，可以让传递进来的所有对象具备相同的逻辑（自定义，如果不调用实际对象的方法）
    // 不同的 InvocationHandler实现，可以决定自己的逻辑
    @SuppressWarnings("unchecked")
    private <T> T getProxy(Class<T> intf, T realObj) {
        return (T) Proxy.newProxyInstance(intf.getClassLoader(), new Class[]{intf},
                new GeneralInvocationHandler(realObj));
    }


}
